#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
支付宝证券交易接口连接器
负责与支付宝证券交易平台进行底层通信，提供基础API调用功能
支持多账户管理
"""

import os
import json
import time
import requests
from datetime import datetime

# 临时模拟Logger类，解决导入问题
class Logger:
    @staticmethod
    def init_logger():
        pass
    
    @staticmethod
    def log_info(msg):
        print(f"INFO: {msg}")
        
    @staticmethod
    def log_warning(msg):
        print(f"WARNING: {msg}")
        
    @staticmethod
    def log_error(msg):
        print(f"ERROR: {msg}")

# 导入必要的工具类
try:
    from utils.security_utils import SecurityUtils
except ImportError:
    # 模拟SecurityUtils类，用于演示
    class SecurityUtils:
        @staticmethod
        def secure_load_credentials(account_id):
            try:
                # 尝试从配置文件加载凭证
                config_path = os.path.join('config', f'{account_id}_credentials.json')
                if os.path.exists(config_path):
                    with open(config_path, 'r', encoding='utf-8') as f:
                        credentials = json.load(f)
                        return credentials.get('api_key'), credentials.get('api_secret')
                return None, None
            except Exception as e:
                print(f"ERROR: 加载凭证失败: {str(e)}")
                return None, None
        
        @staticmethod
        def mask_sensitive_info(info):
            if not info:
                return "None"
            if len(info) <= 4:
                return "*" * len(info)
            return info[:2] + "*" * (len(info) - 4) + info[-2:]

class AlipayAPIConnector:
    """支付宝证券交易接口连接器
    封装与支付宝证券交易平台的底层通信，提供身份认证、数据请求等基础功能
    支持多账户管理"""
    
    # API基础配置
    API_BASE_URL = "https://api.alipay.com/securities/"  # 支付宝证券API基础URL
    API_TIMEOUT = 30  # API调用超时时间(秒)
    RETRY_COUNT = 3  # 失败重试次数
    RETRY_INTERVAL = 1.5  # 重试间隔(秒)
    
    def __init__(self, account_id=None):
        """初始化支付宝API连接器
        
        Args:
            account_id: 账户ID，如果为None则使用默认账户
        """
        # 账户ID
        self.account_id = account_id or "default"
        
        # API凭证
        self.api_key = None
        self.api_secret = None
        self.session_token = None
        
        # 连接状态
        self.is_authenticated = False
        self.last_authentication_time = None
        
        # 请求统计
        self.request_count = 0
        self.error_count = 0
        
        # 尝试加载API凭证
        self.load_api_credentials()
        
    def load_api_credentials(self, account_id=None):
        """从配置文件加载指定账户的API凭证（加密方式）
        
        Args:
            account_id: 账户ID，如果为None则使用当前账户ID
            
        Returns:
            bool: 加载过程是否完成（即使部分解密失败也返回True）
        """
        try:
            # 如果提供了新的账户ID，更新当前账户ID
            if account_id:
                self.account_id = account_id
                # 重置连接状态
                self.is_authenticated = False
                self.session_token = None
            
            # 加载账户凭证
            api_key, api_secret = SecurityUtils.secure_load_credentials(self.account_id)
            
            # 检查凭证是否有效
            if api_key and api_secret:
                self.api_key = api_key
                self.api_secret = api_secret
                Logger.log_info(f"成功加载账户 {self.account_id} 的API凭证，API Key: {SecurityUtils.mask_sensitive_info(api_key)}")
                return True
            else:
                # 凭证无效，尝试使用默认凭证
                Logger.log_warning(f"账户 {self.account_id} 的凭证无效或不存在，使用默认测试凭证")
                self.api_key = "demo_api_key"
                self.api_secret = "demo_api_secret"
                return True
        except Exception as e:
            Logger.log_error(f"加载账户 {self.account_id} 的API凭证失败: {str(e)}")
            return False
            
    def authenticate(self):
        """通过API密钥进行身份认证
        
        Returns:
            bool: 认证是否成功
        """
        try:
            # 检查API凭证是否已加载
            if not self.api_key or not self.api_secret:
                if not self.load_api_credentials():
                    return False
            
            # 构建认证请求
            auth_url = f"{self.API_BASE_URL}auth/token"
            headers = {
                "Content-Type": "application/json",
                "X-API-Key": self.api_key
            }
            payload = {
                "api_secret": self.api_secret
            }
            
            # 发送认证请求
            response = requests.post(auth_url, json=payload, headers=headers, timeout=self.API_TIMEOUT)
            
            # 处理响应
            if response.status_code == 200:
                auth_data = response.json()
                self.session_token = auth_data.get("session_token")
                self.is_authenticated = True
                self.last_authentication_time = datetime.now()
                Logger.log_info(f"账户 {self.account_id} 认证成功，会话令牌已获取")
                return True
            else:
                Logger.log_error(f"账户 {self.account_id} 认证失败，状态码: {response.status_code}, 响应: {response.text}")
                return False
        except Exception as e:
            Logger.log_error(f"账户 {self.account_id} 认证过程中发生错误: {str(e)}")
            return False
            
    def make_request(self, endpoint, params=None, method="GET", retry_count=0):
        """发送API请求的通用方法
        
        Args:
            endpoint: API端点
            params: 请求参数
            method: HTTP方法，默认为GET
            retry_count: 当前重试次数
            
        Returns:
            dict: API响应数据
        """
        try:
            # 检查是否已认证
            if not self.is_authenticated:
                if not self.authenticate():
                    return None
            
            # 构建请求URL
            url = f"{self.API_BASE_URL}{endpoint}"
            
            # 构建请求头，包含会话令牌
            headers = {
                "Content-Type": "application/json",
                "Authorization": f"Bearer {self.session_token}"
            }
            
            # 根据请求方法发送请求
            response = None
            if method.upper() == "GET":
                response = requests.get(url, params=params, headers=headers, timeout=self.API_TIMEOUT)
            elif method.upper() == "POST":
                response = requests.post(url, json=params, headers=headers, timeout=self.API_TIMEOUT)
            elif method.upper() == "PUT":
                response = requests.put(url, json=params, headers=headers, timeout=self.API_TIMEOUT)
            elif method.upper() == "DELETE":
                response = requests.delete(url, params=params, headers=headers, timeout=self.API_TIMEOUT)
            
            # 更新请求统计
            self.request_count += 1
            
            # 处理响应
            if response.status_code in [200, 201, 204]:
                try:
                    return response.json() if response.content else {}
                except json.JSONDecodeError:
                    Logger.log_warning(f"API响应不是有效的JSON格式: {response.text}")
                    return {"raw_response": response.text}
            elif response.status_code == 401:
                # 认证过期，重新认证并尝试请求
                Logger.log_warning(f"API认证过期，尝试重新认证...")
                self.is_authenticated = False
                if retry_count < self.RETRY_COUNT:
                    time.sleep(self.RETRY_INTERVAL)
                    return self.make_request(endpoint, params, method, retry_count + 1)
                else:
                    Logger.log_error(f"达到最大重试次数，请求失败: {url}")
                    return None
            else:
                Logger.log_error(f"API请求失败，状态码: {response.status_code}, 响应: {response.text}")
                self.error_count += 1
                
                # 重试逻辑
                if retry_count < self.RETRY_COUNT:
                    Logger.log_info(f"尝试重试请求 (次数 {retry_count + 1}/{self.RETRY_COUNT})...")
                    time.sleep(self.RETRY_INTERVAL)
                    return self.make_request(endpoint, params, method, retry_count + 1)
                else:
                    Logger.log_error(f"达到最大重试次数，请求失败: {url}")
                    return None
        except Exception as e:
            Logger.log_error(f"API请求过程中发生错误: {str(e)}")
            self.error_count += 1
            
            # 重试逻辑
            if retry_count < self.RETRY_COUNT:
                Logger.log_info(f"尝试重试请求 (次数 {retry_count + 1}/{self.RETRY_COUNT})...")
                time.sleep(self.RETRY_INTERVAL)
                return self.make_request(endpoint, params, method, retry_count + 1)
            else:
                Logger.log_error(f"达到最大重试次数，请求失败: {endpoint}")
                return None
                
    def get_market_data(self, stock_code):
        """获取股票行情数据
        
        Args:
            stock_code: 股票代码
            
        Returns:
            dict: 行情数据
        """
        endpoint = f"market/quotes"
        params = {"symbols": stock_code}
        return self.make_request(endpoint, params)
        
    def place_order(self, stock_code, order_type, quantity, price):
        """下单交易
        
        Args:
            stock_code: 股票代码
            order_type: 订单类型，'buy' 或 'sell'
            quantity: 交易数量
            price: 交易价格
            
        Returns:
            dict: 下单结果
        """
        endpoint = "trade/orders"
        payload = {
            "symbol": stock_code,
            "side": order_type,
            "quantity": quantity,
            "price": price,
            "type": "limit",
            "time_in_force": "day"
        }
        return self.make_request(endpoint, payload, "POST")
        
    def query_order(self, order_id):
        """查询订单状态
        
        Args:
            order_id: 订单ID
            
        Returns:
            dict: 订单信息
        """
        endpoint = f"trade/orders/{order_id}"
        return self.make_request(endpoint)
        
    def cancel_order(self, order_id):
        """取消订单
        
        Args:
            order_id: 订单ID
            
        Returns:
            dict: 取消结果
        """
        endpoint = f"trade/orders/{order_id}/cancel"
        return self.make_request(endpoint, method="POST")
        
    def get_account_balance(self):
        """获取账户资金信息
        
        Returns:
            dict: 资金信息
        """
        endpoint = "account/balance"
        return self.make_request(endpoint)
        
    def get_positions(self):
        """获取持仓信息
        
        Returns:
            dict: 持仓信息
        """
        endpoint = "account/positions"
        return self.make_request(endpoint)
        
    def set_proxy(self, proxy_url):
        """设置HTTP代理
        
        Args:
            proxy_url: 代理服务器URL
            
        Returns:
            bool: 设置是否成功
        """
        try:
            # 为requests设置代理
            self.proxies = {}
            if proxy_url:
                self.proxies = {"http": proxy_url, "https": proxy_url}
            Logger.log_info(f"已设置代理: {proxy_url or '无代理'}")
            # 重置连接状态，需要重新认证
            self.is_authenticated = False
            return True
        except Exception as e:
            Logger.log_error(f"设置代理失败: {str(e)}")
            return False

# 模块初始化完成后的提示
if __name__ == "__main__":
    Logger.log_info("支付宝API连接器模块加载完成")
    # 示例使用
    connector = AlipayAPIConnector()
    Logger.log_info(f"连接器初始化状态: 认证={connector.is_authenticated}")